/*
  输出满足特定条件的格子
  题目描述
    在一个 n * m 的矩阵（矩阵中左上角为第 0 行第 0 列）中，有 k 个格子被涂黑，其他均为白色。
    现在有 q 次询问，且询问有两种：
      - 第一种：输出第 x 行的所有被涂黑的格子的列号。
      - 第二种：输出第 x 列的所有被涂黑的格子的行号。

    提醒：本题输入输出量较大，请使用 scanf/printf 而不是 cin/cout 进行输入输出。
  输入
    第一行为 4 个数 n,m,k,q，含义如前所示。
    接下来 k 行每行两个整数 x,y，表示矩阵中第 x 行第 y 列的格子被涂黑。保证任意两个格子不重复。
    接下来 q 行每行两个整数 p,x，若 p 为 1 表示第一种询问，p 为 2 表示第二种询问。
  输出
    按照询问的要求输出。若有多个满足条件的格子，按照这些格子被涂黑的先后顺序输出。
  样例输入
    5 5 10 4
    3 1
    5 4
    5 1
    3 2
    1 2
    4 3
    5 5
    2 4
    5 2
    4 5
    1 3
    2 2
    1 5
    2 3
  样例输出
    1 2
    3 1 5
    4 1 5 2
    4
  数据范围
    1 <= n, m, q <= 10^5, 1 <= k <= min(5 * 10^5, n * m)。
    数据保证所有询问中输出的格子总个数不超过 5 * 10^6。
*/

#include <bits/stdc++.h>

using namespace std;

/*
  说明:
    由于题目中要求输出如下 2 种统计结果：
     a). 通过矩阵的行号查询对应的这一行有多少个格子每涂黑
     b). 通过矩阵的行号查询对应的这一行有多少个格子每涂黑
    为了方便快速提供查询结果, 我们分别定义表示一行有哪些格子被涂黑, 以及表示一列中有哪些格式被涂黑!
*/
vector <int> hang[100005]; // hang[i] 表示: 矩阵的第 i 行中哪些列对应的格子被涂黑
vector <int> lie[100005];  // lie[i]  表示: 矩阵的第 i 列中哪些行对应的格子被涂黑

int main() {
    /*
      本题题目说明中有如下字样:
        "提醒：本题输入输出量较大，请使用 scanf/printf 而不是 cin/cout 进行输入输出。"
      针对待有类似这种描述的编程题, 乔斯给的解释及解决方案如下:
        cin/cout 因为默认同步 stdin/stdout 而变慢，并产生更多的系统调用而受到性能影响，
        可以在 main 函数开头加入下面代码加速：
          ios::sync_with_stdio(false);
          cin.tie(0);
    */
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m, k, q;
    cin >> n >> m >> k >> q;

    for (int i  = 1; i <= k; i++) {
        int x, y;
        cin >> x >> y;
        hang[x].push_back(y);
        lie[y].push_back(x);
    }

    for (int i = 1; i <= q; i++) {
        int a, b;
        cin >> a >> b;
        if (a == 1) { // 输出 b 行所有涂黑的格子的列号
            for (int j = 0; j < hang[b].size(); j++) {
                cout << hang[b][j] << " ";
            }
            cout << endl;
        } else {      // 输出 b 列所有涂黑的格子的行号
            for (int j = 0; j < lie[b].size(); j++) {
                cout << lie[b][j] << " ";
            }
            cout << endl;
        }
    }

    return 0;
}